package ar.com.agea.processes.alert.job

import org.codehaus.groovy.grails.web.context.ServletContextHolder
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes
import org.hibernate.FlushMode
import org.hibernate.Session
import org.quartz.Job
import org.quartz.JobDataMap
import org.quartz.JobExecutionContext
import org.quartz.JobExecutionException
import org.springframework.context.ApplicationContext
import org.springframework.orm.hibernate3.SessionFactoryUtils
import org.springframework.orm.hibernate3.SessionHolder
import org.springframework.transaction.support.TransactionSynchronizationManager

import ar.com.agea.exception.ApplicationException
import ar.com.agea.processor.alert.controller.AlertNotifierController
import ar.com.agea.services.inspector.gadget.delegate.InspectorGadgetServiceClient
import ar.com.agea.services.inspector.gadget.delegate.impl.InspectorGadgetServiceClientImpl
import ar.com.agea.services.inspector.gadget.dto.JobDTO
import ar.com.agea.services.inspector.gadget.dto.JobInstanceDTO
/**
 * 
 * @author mcapolupo
 *
 */
class AlertNotificationJob implements Job {

	def alertNotifierController = new AlertNotifierController()

	public void execute(JobExecutionContext jobContext) throws JobExecutionException {
		ApplicationContext context = (ApplicationContext) ServletContextHolder.getServletContext().getAttribute(GrailsApplicationAttributes.APPLICATION_CONTEXT);
		def sessionFactory =  context.getBean('sessionFactory')
		Session session = null;
		try {
		   session = SessionFactoryUtils.getSession(sessionFactory, false);
		}
		// If not already bound the Create and Bind it!
		catch (java.lang.IllegalStateException ex) {
		   session = SessionFactoryUtils.getSession(sessionFactory, true);
		   TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(session));
		}
	   session.setFlushMode(FlushMode.AUTO);
	   if( log.isDebugEnabled()) println ("Hibernate Session is bounded to Job thread");
		
		JobDataMap jdMap = jobContext.getJobDetail().getJobDataMap();
		def nameJob = jdMap.get("nameJob").toString();
		def intervalCode = jdMap.get("intervalCode").toString();
		
		InspectorGadgetServiceClient inspectorGadgetServiceClient = new InspectorGadgetServiceClientImpl()
		
		if (!inspectorGadgetServiceClient.isRunning()) {
			printn ("Client is not running");
			System.exit(-1);
		}

		JobDTO job = inspectorGadgetServiceClient.findJobDTOByName(nameJob);
		JobInstanceDTO jobInstanceDTO = inspectorGadgetServiceClient.startInstanceFor(job);

		// execute job
		log.info "Alert Notification Monthly is running"
		try {
			alertNotifierController.notifyAlert(intervalCode)
			inspectorGadgetServiceClient.finishInstance(jobInstanceDTO);
			println ("###### Process ended successfully for intervalcode: ${intervalCode} ########");
		}

		catch(ApplicationException error) {
			inspectorGadgetServiceClient.crashInstance(jobInstanceDTO, error.message);
			println ("###### Process ended failure for intervalcode: ${intervalCode} ########");
		}
		
		
		try {
			SessionHolder sessionHolder = (SessionHolder)
			TransactionSynchronizationManager.unbindResource(sessionFactory);
			if(!FlushMode.MANUAL.equals(sessionHolder.getSession().getFlushMode())) {
			  sessionHolder.getSession().flush();
			}
			SessionFactoryUtils.closeSession(sessionHolder.getSession());
			if( log.isDebugEnabled()) log.debug("Hibernate Session is unbounded from Job thread and closed");
		  }
		  catch (Exception ex) {
			ex.printStackTrace();
		  }
		
	}
	
}
